package cn.iocoder.yudao.module.hs.service.device;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.hs.controller.admin.device.vo.DevicePageReqVO;
import cn.iocoder.yudao.module.hs.controller.admin.device.vo.DeviceRespVO;
import cn.iocoder.yudao.module.hs.controller.admin.device.vo.DeviceSaveReqVO;
import cn.iocoder.yudao.module.hs.controller.admin.device.vo.DeviceTestReqVO;
import cn.iocoder.yudao.module.hs.dal.dataobject.device.DeviceDO;
import cn.iocoder.yudao.module.hs.dal.dataobject.warehouse.WarehouseDO;
import cn.iocoder.yudao.module.hs.dal.mysql.device.DeviceMapper;
import cn.iocoder.yudao.module.hs.enums.warehouse.WarehouseTypeEnum;
import cn.iocoder.yudao.module.hs.netty.RFIDData;
import cn.iocoder.yudao.module.hs.netty.RFIDUtil;
import cn.iocoder.yudao.module.hs.netty.Transmission;
import cn.iocoder.yudao.module.hs.service.warehouse.WarehouseService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.netty.channel.Channel;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.hs.enums.ErrorCodeConstants.DEVICE_NOT_EXISTS;

/**
 * 基站信息 Service 实现类
 *
 * @author 航盛
 */
@Service
@Validated
public class DeviceServiceImpl implements DeviceService {

    @Resource
    private DeviceMapper deviceMapper;
    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private WarehouseService warehouseService;

    @Override
    public Long createDevice(DeviceSaveReqVO createReqVO) {
        // 插入
        DeviceDO device = BeanUtils.toBean(createReqVO, DeviceDO.class);
        deviceMapper.insert(device);
        // 返回
        return device.getId();
    }

    @Override
    public void updateDevice(DeviceSaveReqVO updateReqVO) {
        // 校验存在
        validateDeviceExists(updateReqVO.getId());
        // 更新
        DeviceDO updateObj = BeanUtils.toBean(updateReqVO, DeviceDO.class);
        deviceMapper.updateById(updateObj);
    }

    @Override
    public void deleteDevice(Long id) {
        // 校验存在
        validateDeviceExists(id);
        // 删除
        deviceMapper.deleteById(id);
    }

    private void validateDeviceExists(Long id) {
        if (deviceMapper.selectById(id) == null) {
            throw exception(DEVICE_NOT_EXISTS);
        }
    }

    @Override
    public DeviceDO getDevice(Long id) {
        return deviceMapper.selectById(id);
    }

    @Override
    public PageResult<DeviceRespVO> getDevicePage(DevicePageReqVO pageReqVO) {
        AdminUserRespDTO user = adminUserApi.getUser(getLoginUserId());
        WarehouseDO warehouse = warehouseService.getWarehouse(user.getWarehouseId());
        if (WarehouseTypeEnum.TRIPARTITE.getType().equals(warehouse.getWarehouseType())) {
            pageReqVO.setWarehouseId(warehouse.getId());
        }
        PageResult<DeviceRespVO> deviceRespVOPageResult = BeanUtils.toBean(deviceMapper.selectPage(pageReqVO), DeviceRespVO.class);
        if (CollUtil.isNotEmpty(deviceRespVOPageResult.getList())) {
            for (DeviceRespVO deviceRespVO : deviceRespVOPageResult.getList()) {
                if (Transmission.getChannelMap().containsKey(deviceRespVO.getCode())) {
                    deviceRespVO.setConnected(true);
                    deviceRespVO.setLastHeartbeatTime(Transmission.getChannelExpireTimeMap().get(deviceRespVO.getCode()));
                } else {
                    deviceRespVO.setConnected(false);
                }
            }
        }
        return deviceRespVOPageResult;
    }

    @Override
    public DeviceDO getDeviceByCode(String code) {
        return deviceMapper.selectOne(DeviceDO::getCode, code);
    }

    @Override
    public List<DeviceDO> getDeviceByIds(List<String> deviceIds) {
        return deviceMapper.selectList(deviceIds);
    }

    @Override
    public void disconnect(String deviceId) {
        Transmission.removeChannel(deviceId);
    }

    @Override
    public void test(DeviceTestReqVO testReqVO) {
        // 1-红色，2-蓝色，3-绿色，4-黄色
        int color = 0;
        switch (testReqVO.getColor()) {
            case RFIDUtil.RED:
                color = 1;
                break;
            case RFIDUtil.BLUE:
                color = 2;
                break;
            case RFIDUtil.GREEN:
                color = 3;
                break;
            case RFIDUtil.YELLOW:
                color = 4;
                break;
        }
        String command = RFIDUtil.getCommand(testReqVO.getRfidCode(), color, true, testReqVO.getBuzzingSeconds(), true);
        if (Transmission.getChannelMap().containsKey(testReqVO.getDeviceId())) {
            Channel channel = Transmission.getChannelMap().get(testReqVO.getDeviceId());
            channel.writeAndFlush(command);
        }
    }

    @Override
    public List<String> getRfidList(String deviceId) {
        List<RFIDData> lastRFIDList = RFIDData.getLastRFIDList();
        return lastRFIDList.stream().filter(rfidData -> rfidData.getDeviceId().equals(deviceId)).collect(Collectors.toList()).stream().map(RFIDData::getRfidCode).collect(Collectors.toList());
    }

}
